import mylist.IList;

//这个是单链表
public class MySingleList implements IList {

    //节点的内部类
    class ListNode{//~~~博哥加了修饰符：public

        public int val;
        public ListNode next;

        public ListNode(int val){
            this.val = val;
        }

    }

    public ListNode head;//“头指针”

   /**
    * 博哥写了这个方法，接口里边没有，不知道干啥用的
    *  public void createList() {
       ListNode node1 = new ListNode(12);
       ListNode node2 = new ListNode(23);
       ListNode node3 = new ListNode(34);
       ListNode node4 = new ListNode(45);
       ListNode node5 = new ListNode(56);

       node1.next = node2;
       node2.next = node3;
       node3.next = node4;
       node4.next = node5;

       this.head = node1;
    }          */


    /**
     * 下面是重写的方法（实现的过程中，可能会封装一些私有方法）
     * 之后
     * 还会写一些  此类 特有方法
     */


    /*特有方法public MySingleList()*/
    //此类的 构造方法。
    //这个是刚才 Generata-override 全选出来的？
    //还是 idea提示，不小心点出来的？
    //博哥的代码里边没有这个
    public MySingleList() {
        super();
    }


    @Override
    public void addFirst(int data) {


        //这个方法是：插入一个元素——先根据所给参数（元素），生成一个新的节点，再把新节点插入到链表中
        ListNode newNode = new ListNode(data);//生成一个新节点


        newNode.next = this.head;
        this.head = newNode;
        //这里，无论原来链表有没有元素，都满足这个逻辑
        //所以，不需要分支语句if-else,进行分情况的写法

        //OK，新节点已经插入完成。

    }

    @Override
    public void addLast(int data) {

        //原因：同public void addFirst(int data)
        ListNode newNode = new ListNode(data);
        ListNode cur = this.head;

        //尾插需要分情况，因为head是否需要改变，与head初始是否为null，即，初始链表有没有节点，有影响
        if(this.head == null){

            this.head = newNode;
            return;

        }

        while(cur.next != null){

            cur = cur.next;

        }
        //来到了最后一个元素的位置
        //将元素插入即可
        //newNode.next = cur.next;//因为是尾插，所以不需要这一句——“绑定后继结点”
        cur.next = newNode;

    }



    @Override
    public void addIndex(int index, int data) {



        //先排查所给位置是否合法。
        if(index < 0 || index > size()){//这里需要写一个方法，计算链表大小

            //抛自定义异常
            try{
                throw new PosIsNotLegal("所给插入位置不合法。");
            }catch(PosIsNotLegal e){
                e.printStackTrace();
                System.out.println("出错啦！！！"+e.getMessage());
                return;//return;//!!!抛完异常也要return，异常只能“截断”其所在代码块的执行（对吧？？？？）

            }

        }

        //能走到这里，说明前边都没有异常出现，下标没问题
        //将所给元素，变成节点，插入到指定位置
        ListNode newNode = new ListNode(data);//所给元素->节点
        ListNode cur = this.head;

        int count = 0;//这里认为index指的是从0开始计的下标哈~
        while(count < index-1){

            cur = cur.next;
            count++;

        }

        newNode.next = cur.next;
        cur.next = newNode;

    }

    @Override
    public boolean contains(int key) {

        ListNode cur = this.head;
        if(this.head == null ){
            return false;
        }
        if(this.head.val == key){
            return true;
        }
        while(cur.next != null){
            if(cur.next.val == key){

                return true;

            }
            cur = cur.next;
        }


        return false;
    }

    @Override
    public void remove(int key) {
        //先判断是否有这个数字
        if(!contains(key)){//不存在，返回
            return;
        }
        if(head.val == key){
            head = head.next;
            return;
        }
        ListNode cur = this.head;
        while(cur != null){
            if(cur.next.val == key){

                cur.next = cur.next.next;
                break;

            }
            cur = cur.next;
        }



    }

    @Override
    public void removeAllKey(int key) {
        ListNode cur = this.head;
        ListNode nextNode = cur.next;
        if(cur == null){

            return;

        }
        if(cur.val == key){

            //
            cur.next = nextNode;

        }

        while(cur.next != null){

            if(cur.next.val == key){
                cur.next = cur.next.next;
                continue;
            }
            cur = cur.next;

        }

    }

    @Override
    public int size() {

        if(this.head == null){
            return 0;
        }

        ListNode cur = this.head;
        int count = 0;
        while (cur != null){
            cur = cur.next;
            count++;

        }
        return count;
    }

    @Override
    public void clear() {

        //this.head = null;

        //或者
        ListNode cur = this.head;
        ListNode nextNode = cur.next;

        while(cur != null){

            //
            cur.val = 0;
            nextNode = cur.next;
            cur.next = null;
            cur = nextNode;

        }
        this.head = null;


    }

    @Override
    public void display() {

        ListNode cur = this.head;
        while(cur != null){
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();


    }



}
